package cn.xiaolang.thread.lock;

/**
 * 可重入锁示例(基于Synchronized): 
 * 意味着线程可以进入它已经拥有的锁的同步代码块
 * 
 * 重入锁实现可重入性原理或机制是：
 * 1.每一个锁关联一个线程持有者和计数器，当计数器为 0 时表示该锁没有被任何线程持有；
 * 2.当某一线程请求成功后，JVM会记下锁的持有线程，并且将计数器+1；
 * 3.而该持有锁的线程如果再次请求这个锁，就可以再次拿到这个锁，同时计数器会递增；
 * 4.此时其它线程请求该锁，则必须等待；
 * 5.当线程退出同步代码块时，计数器会递减，如果计数器为 0，则该锁释放。
 * 
 * @author fuhw/DeanKano
 * @date 2019-01-08
 */
public class MyReentrantLock {

	private boolean isLocked = false;
	private Thread lockedBy = null;
	private int lockedCount = 0;

	public synchronized void lock() throws InterruptedException {
		Thread currentThread = Thread.currentThread();
		while (isLocked && currentThread != lockedBy) {
			wait();
		}
		isLocked = true;
		lockedCount++;
		lockedBy = currentThread;
	}

	public synchronized void unlock() {
		Thread currentThread = Thread.currentThread();
		if (currentThread == lockedBy) {
			lockedCount--;
			if (lockedCount == 0) {
				isLocked = false;
				notify();
			}
		}
	}

}
